package com.dl.base.utils

import kotlinx.coroutines.suspendCancellableCoroutine
import java.io.*
import java.lang.Exception
import java.lang.StringBuilder
import java.nio.charset.Charset
import kotlin.coroutines.resume

object AutoInstallUtil {

    fun install(packageName: String, filePath: String): Boolean {
        val file = File(filePath)
        var su: Process? = null
        try {
            su = Runtime.getRuntime().exec("/system/bin/su")
            val cmd = "chmod 666 $filePath\nexit\n"
            su.outputStream.write(cmd.toByteArray())
            if (su.waitFor() != 0 || !file.canRead() || !file.canWrite()) {
                throw SecurityException()
            }
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        }
        val args = arrayOf("pm", "install", "-i", packageName, "--user", "0", "-r", filePath)
        val processBuilder = ProcessBuilder(*args)
        var process: Process? = null
        var successResult: BufferedReader? = null
        var errorResult: BufferedReader? = null
        val successMsg = StringBuilder()
        val errorMsg = StringBuilder()
        try {
            process = processBuilder.start()
            successResult = BufferedReader(InputStreamReader(process.inputStream))
            errorResult = BufferedReader(InputStreamReader(process.errorStream))
            var s: String?
            while (successResult.readLine().also { s = it } != null) {
                successMsg.append(s)
            }
            while (errorResult.readLine().also { s = it } != null) {
                errorMsg.append(s)
            }
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                successResult?.close()
                errorResult?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            process?.destroy()
        }
        return successMsg.toString().contains("Success") || successMsg.toString()
            .contains("success")
    }


    suspend fun install(apkPath: String) = suspendCancellableCoroutine<Boolean> { continuation ->
        var result = false
        // 申请su权限
        val process = Runtime.getRuntime().exec("su")
        DataOutputStream(process.outputStream).use {
            // 执行pm install命令
            val command = "pm install -r $apkPath\n"
            it.write(command.toByteArray(Charset.forName("utf-8")))
            it.flush()
            it.writeBytes("exit\n")
            it.flush()
        }
        process.waitFor()
        BufferedReader(InputStreamReader(process.errorStream)).use {
            val line = StringBuilder()
            while (true) {
                line.append(it.readLine() ?: break)
            }
            // 如果执行结果中包含Failure字样就认为是安装失败，否则就认为安装成功
            if (!line.toString().contains("Failure")) {
                result = true
            }
        }
        continuation.resume(result)
    }
}